//////////////////////////////////////////////////////////////////////////
//
// GAM204
// Node
// Node.h
// 
// Grant Johnson
// Qantm College
// 27/10/2010
//
//////////////////////////////////////////////////////////////////////////

#ifndef NODE_H
#define NODE_H

#include <vector>
#include "Renderer.h"
#include "Cube.h"
#include "AABB.h"

class RenderParams;

class Node
{
public:
	Node();
	//Custom C'tor - Setup the node
	Node(int a_max, AABB* a_aabb);
	Node(int a_max, AABB* a_aabb, Renderer::DrawableObjectList* a_pDrawable);
	~Node();
	
	//////////////////////////////////////////////////////////////////////////
	// Converts the node into a branch node. It creates 8 child nodes to fill
	// the child nodes vector and then clears the drawable object list.
	//
	// Paramaters:
	// None
	//
	// Returns void
	//
	//////////////////////////////////////////////////////////////////////////
	void ConvertToBranch();

	//////////////////////////////////////////////////////////////////////////
	// Whether or not this node has children, if it does have children than
	// it is a branch node, if it does not, than it is a leaf node
	//
	// Paramaters:
	// None
	//
	// Returns true if it is a branch node
	// Returns false if it is a leaf node
	//
	//////////////////////////////////////////////////////////////////////////
	bool HasChildren();

	//////////////////////////////////////////////////////////////////////////
	// Attempt to add a list of drawable objects to the node. The given list
	// comes from the parent node. Iterates through the list of drawables and
	// checks to see if their bounding box overlaps the node at all
	//
	// Paramaters:
	// a_pDrawable, a list of drawable objects to attempt to add to this node
	//
	// Returns void
	//
	//////////////////////////////////////////////////////////////////////////
	void AddDrawables(Renderer::DrawableObjectList* a_pDrawable);
	
	//////////////////////////////////////////////////////////////////////////
	// Get the list of drawable objects held by the node
	//
	// Paramaters:
	// None
	//
	// Returns a drawable object list of the leaf nodes drawables
	//
	//////////////////////////////////////////////////////////////////////////
	Renderer::DrawableObjectList& GetObjectList() { return m_pDrawableObjectList; }

	//////////////////////////////////////////////////////////////////////////
	// Get the vector of child node pointers
	//
	// Paramaters:
	// None
	//
	// Returns a vector of node pointers from the child nodes 
	//
	//////////////////////////////////////////////////////////////////////////
	std::vector<Node*> GetNodes() { return m_pChildNodes; }

	//////////////////////////////////////////////////////////////////////////
	// Get the child node at the given index
	//
	// Paramaters:
	// a_index, the node index to return
	//
	// Returns a pointer to the node at the given index
	//
	//////////////////////////////////////////////////////////////////////////
	Node* GetChild(int a_index) { return m_pChildNodes.at(a_index); }

	AABB& GetAABB() { return m_aabb; }

private:
	//8 pointers to this nodes child nodes - this is used if it's a branch node
	std::vector<Node*> m_pChildNodes;

	//List of pointers to drawable objects contained in this node - this is used if its a leaf node
	Renderer::DrawableObjectList m_pDrawableObjectList;

	//Max number of objects before splitting into child nodes
	int m_maxObjects;
	
	//Whether this node is a branch or a leaf
	bool m_hasChildren;

	AABB m_aabb;
};

#endif //NODE_H